import time, os

from nevow import rend, loaders, tags as T
from nevow import athena, static
from conquest.simulation.planet import PlanetManager
from twisted.internet import task

from math import floor

from twisted.python import util

manager = PlanetManager(time_per_tick = 6)

manager.add_planet()
manager.start()


class Planet(athena.LiveFragment):
    jsClass = u"Planets.Planet"

    docFactory = loaders.xmlstr('''\
<div xmlns:nevow="http://nevow.com/ns/nevow/0.1"
     xmlns:athena="http://divmod.org/ns/athena/0.7"
     nevow:render="liveFragment">
     <table>
        <thead>
        <tr>
            <td><h4>Planet:</h4></td>
            <td id="planet_id">
                <h4><nevow:invisible nevow:render="planetid" /></h4>
            </td>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>Habitability rating:</td>
            <td id="habitability_rating">
                <nevow:invisible nevow:render="habitability" />
            </td>
        </tr>
        <tr>
            <td>Metal rating:</td>
            <td id="metal_rating">
                <nevow:invisible nevow:render="metal" />
            </td>
        </tr>

        <tr>
            <td>Tick:</td>
            <td id="tick"></td>
        </tr>
        <tr>
            <td>Tick Multiplier:</td>
            <td id="tick_multiplier_value">1</td>
        </tr>
        <tr>
            <td>Population:</td>
            <td id="population"></td>
        </tr>
        <tr>
            <td>Houses:</td>
            <td id="houses"></td>
        </tr>
        <tr>
            <td>Food:</td>
            <td id="food"></td>
        </tr>
        <tr>
            <td>Metal:</td>
            <td id="metal"></td>
        </tr>
        <tr>
            <td>Research:</td>
            <td id="research"></td>
        </tr>
        </tbody>
     </table>
     <br/>
     
     <input type="text" id="tick_multiplier_text" size="12" maxlength="12" value="1"></input>
     <a href="#"><athena:handler event="onclick" handler="set_multiplier" />
         Set tick multiplier
     </a>
     <br/>
     <br/>
     <br/>
     <table border="1" frame="border" rules="all">
        <thead>
        <tr>
            <td>
                Industry
            </td>
            <td>
                Employed (percent)
            </td>
            <td>
                Goal
            </td>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td>Housing</td>
            <td id="housing"></td>
            <td><input id="housing_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Mining</td>
            <td id="mining"></td>
            <td><input id="mining_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Food</td>
            <td id="fooding"></td>
            <td><input id="fooding_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Ships</td>
            <td id="ships"></td>
            <td><input id="ships_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Troops</td>
            <td id="troops"></td>
            <td><input id="troops_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Research</td>
            <td id="researching"></td>
            <td><input id="researching_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>Health</td>
            <td id="health"></td>
            <td><input id="health_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Police</td>
            <td id="police"></td>
            <td><input id="police_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Military</td>
            <td id="military"></td>
            <td><input id="military_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Infrastructure</td>
            <td id="infrastructure"></td>
            <td><input id="infrastructure_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Entertainment</td>
            <td id="entertainment"></td>
            <td><input id="entertainment_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        <tr>
            <td>Unemployment</td>
            <td id="unemployment"></td>
            <td><input id="unemployment_goal" type="text" size="10" maxlength="10" disabled="true" value=""/></td>
        </tr>
        </tbody>
     </table>
     <br/>
     <div>
        <a href="#"><athena:handler event="onclick" handler="start" />
            Start updating
        </a>

        <br/>
        <a href="#"><athena:handler event="onclick" handler="stop" />
            Stop updating
        </a>
        <p>Note: Time does not stop even while updating is disabled.</p>
     </div>
     <a href="#"><athena:handler event="onclick" handler="setGoals" />
            Set Goals
        </a>
     <script type="text/javascript">
     function toggleEdit() {
         var new_val = true;
         if (document.getElementById('housing_goal').disabled) {
            new_val = false;
         }
         document.getElementById('housing_goal').disabled=new_val;
         document.getElementById('mining_goal').disabled=new_val;
         document.getElementById('fooding_goal').disabled=new_val;
         document.getElementById('ships_goal').disabled=new_val;
         document.getElementById('troops_goal').disabled=new_val;
         document.getElementById('researching_goal').disabled=new_val;
         document.getElementById('health_goal').disabled=new_val;
         document.getElementById('police_goal').disabled=new_val;
         document.getElementById('military_goal').disabled=new_val;
         document.getElementById('infrastructure_goal').disabled=new_val;
         document.getElementById('entertainment_goal').disabled=new_val;
         document.getElementById('unemployment_goal').disabled=new_val;

     }
     </script>
     <input type='button' onclick='toggleEdit()' value='Toggle Goal Edit Mode' />
</div>
''')

    running = False

    def start(self):
        if self.running:
            return
        self.loop = task.LoopingCall(self.updatePlanet)
        self.loop.start(6)
        self.running = True
    athena.expose(start)

    def stop(self):
        if not self.running:
            return
        self.loop.stop()
        self.running = False
    athena.expose(stop)

    def set_tick_multiplier(self, multiplier):
        try:
            temp = int(multiplier)
            if temp < 0 or temp > 10000000:
                return
            self.planet.lock.acquire()
            self.planet.tick_multiplier = temp
            self.planet.lock.release()
        except:
            return
    athena.expose(set_tick_multiplier)

    key_list = ['housing', 'mining', 'food', 'ships', 'troops', 'research',\
                    'health', 'police', 'military', 'infrastructure',\
                    'entertainment', 'unemployment']
    def set_goals(self, temp):
        try:
            temp_total = 0.0
            for x in xrange(len(self.key_list)):
                temp_float = float(temp[x]) / 100.0
                if temp_float < 0 or temp_float > 1:
                    return
                temp_total += temp_float

            if temp_total < 0.999999 or temp_total > 1.000001:
                return
        except KeyError:
            return
        except ValueError:
            return
        except IndexError:
            return

        self.planet.lock.acquire()
        for value, key in zip(temp, self.key_list):
            self.planet.goal[key] = float(value) / 100.0
        self.planet.lock.release()



    athena.expose(set_goals)

    def _oops(self, err):
        log.err(err)
        if self.running:
            self.loop.stop()
            self.running = False

    def render_planetid(self, ctx, data):
        return self.planet.id

    def render_habitability(self, ctx, data):
        return self.planet.hab

    def render_metal(self, ctx, data):
        return self.planet.met

    def updatePlanet(self):
        self.planet.lock.acquire()
        fields = [unicode(str(self.planet.curr_tick), 'ascii'),
                  unicode(str(self.planet.population), 'ascii'),
                  unicode(str(self.planet.houses), 'ascii'),
                  unicode(str(self.planet.food), 'ascii'),
                  unicode(str(self.planet.metal), 'ascii'),
                  unicode(str(self.planet.research), 'ascii')]

        for key in self.key_list:
            temp_str = str(self.planet.employment[key])
            temp_str += " ("
            temp_str += str(float(self.planet.employment[key]) / \
                            floor(self.planet.population) * 100)
            temp_str += "%)"
            fields.append(unicode(temp_str, 'ascii'))
            fields.append(unicode(str(self.planet.goal[key] * 100.0), 'ascii'))

        self.callRemote('setFields', fields).addErrback(self._oops)
        self.planet.lock.release()

class PlanetPage(athena.LivePage):
    docFactory = loaders.xmlstr("""\
<html xmlns:nevow="http://nevow.com/ns/nevow/0.1">
    <head>
        <nevow:invisible nevow:render="liveglue" />
    </head>
    <body>
        <div nevow:render="planet" />
    </body>
</html>
""")

    addSlash = True

    def __init__(self, *a, **kw):
        super(PlanetPage, self).__init__(*a, **kw)
        self.jsModules.mapping[u'Planets'] = util.sibpath(__file__, 'planet.js')

    def childFactory(self, ctx, name):
        ch = super(PlanetPage, self).childFactory(ctx, name)
        if ch is None:
            p = util.sibpath(__file__, name)
            if os.path.exists(p):
                ch = static.File(file(p))
        return ch

    def render_planet(self, ctx, data):
        c = Planet()
        c.planet = self.planet
        c.page = self
        return ctx.tag[c]

    def render_debug(self, ctx, data):
        f = athena.IntrospectionFragment()
        f.setFragmentParent(self)
        return ctx.tag[f]


class PlanetMain(rend.Page):
    docFactory = loaders.stan(T.html[T.head(title = "Planets Main"),
                              T.body[T.p["Planets go here."]]])

    def childFactory(self, ctx, name):
        if manager.has_planet(name):
            x = PlanetPage()
            x.planet = manager.get_planet(name)
            return x

class Root(rend.Page):
    addSlash = True
    
    docFactory = loaders.stan(T.html[T.head(title = "Blah"),
                   T.body[T.p["Go away now"]]])

    def child_planet(self, ctx):
        return PlanetMain(None, None)
